Creating smooth rollOver and rollOut Effects

In the Flex framework, if you have a rollOver and rollOut effect set on a particular component, you might experience some very jerky movement when you roll over and out of the components quickly. Here is an example: Non-Smooth Effects. Try rolling over and out of the Buttons quickly. You will notice that the movement is not smooth. The reason for this is explained in bug SDK-430.

” Currently in rollOver if the user roll’s out before the rollOver effect finishes, the framework will call end on the rollOver effect, then play the roll out effect. The result is jarring.”

To get around this, you need to manage each effect instance that plays. If the instance has not completed, then, your rollOut effect should be to do a “reverse” on the effect. Jason Szeto posted a simple example of how to do this in the bug. Download the bug file “ZoomRollOver.mxml”. Here is the code:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”&gt;
<mx:Script>
import mx.effects.*;
import mx.effects.effectClasses.*;
import mx.events.*;
import mx.core.*;

public var resizeInst:ResizeInstance;

public function handleMouse(event:MouseEvent):void
{
if (resizeInst)
resizeInst.reverse();
else
r.play([event.currentTarget],event.type==MouseEvent.MOUSE_OUT);
}

</mx:Script>

<mx:Resize id=”r” heightTo=”100″ heightFrom=”22″ effectStart=”resizeInst = ResizeInstance(event.effectInstance);” effectEnd=”resizeInst=null”/>

<mx:Button width=”200″ mouseOver=”handleMouse(event)” mouseOut=”handleMouse(event)” />
</mx:Application>

I have modified this example to work for a group of Buttons. This involved managing all of the effectInstances that were playing in an Array (because multiple instances could be running at once). Hope this helps someone since I’ve seen this asked about on multiple forums.

Demo: ZoomRollOverGroup_withEffects.swf

Sample Code: ZoomRollOverGroup_withEffects.mxml

I’m not sure this is the cleanest solution, but it seems to work. Modify it as much as you’d like.

18 responses

  1. Try using the Tweener class… I think you will save a lot of coding….

  2. Continue making your work and see the Tweener class too, good work!

  3. when I have to do stuff like that on transitions I’ve ended up extending the effect classes that I need and, on their instances, I override the end() method like this:


    override public function end() :void {
    if (tween) {
    tween.stop();
    tween.dispatchEvent(new TweenEvent(TweenEvent.TWEEN_END));
    tween = null;
    }
    super.end();
    }

    … so I can use them as usual on the rest the application.

  4. I think you will save a lot of coding….

  5. Condo says : I absolutely agree with this !

  6. Somehow i missed the point. Probably lost in translation 🙂 Anyway … nice blog to visit.

    cheers, Angina!

  7. Huh, very interesting!
    I know a lot of methods to use it

  8. wow!!, why so much coding, why not just wrap it in an extended button class using the original zoomrollovercode then just instance them out to the application, each will contain there own instance of the listener’s and function interdependently of each, you can then create custom handlers at runtime to alter resize height etc through your new custom component

  9. Unfortunately it’s not an effective solution. I wish it was because the built in effects for flex right now are rather lacking in functionality. If you want to see the code break just change the resize effect to a glow effect.

    and when you scroll over fast a button will intermittently remain on.

  10. what’s about rollOverEffect and rollOutEffect ?

  11. @Vladimir: The problem with rollOverEffect and rollOutEffect that this post is trying to address is that when you roll in and out of components quickly, the effects aren’t smooth because the effects immediately jump to the end of their effect. See bug SDK-430. There is a sample uploaded there that shows the problem with just using rollOverEffect and rollOutEffect.

  12. I would suggest changing mouseOver/mouseOut to rollOver/rollOut and MouseEvent.MOUSE_OUT to MouseEvent.ROLL_OUT

    because if you have any children inside what your changing rolling over children wont trigger the mouseOut

    I’m using this and so far I’m unable to make it bug out so it works well enough for me 🙂

  13. I was wondering, currently the code works for rolling over/out of an object and then the object is effected. But I was wondering how this would effect a different object.

    Example: I have an image, when you roll over the image a box rolls up from the bottom with some text about the image.

    The event.currentTarget is read only and that is mostly my problem.

  14. Can anyone tell me how to do this in a Canvas with a few children?
    When you roll over the children, the effect becomes intermitent

  15. How i can add more buttons inside a button with the same effect

  16. thx. simple straightforward demos of this is exactly what i was looking forward

  17. ryanbbeard, can u please provide a simple example? I can’t make my button roll out whatever I try. 10x in advance

  18. mayank chandela | Reply

    nice blog man….thanks ton for sharing such a wonderful code it just saved a lot code for me 🙂

Leave a comment